package cs5226.tags;

import java.io.IOException;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.SimpleTagSupport;

import cs5226.model.AwrSetting;
import cs5226.model.SingleValueStatistics;
import cs5226.util.StringUtil;

public class AggregatedValue extends SimpleTagSupport {
	
	private String statistics;

	@Override
	public void doTag() throws JspException, IOException {
		JspWriter out = getJspContext().getOut();
		
		if (StringUtil.isNullOrBlank(statistics)) {			
			out.println ("No statistics specified!");
			return;
		}
		
		List<? extends SingleValueStatistics> statList = (List<? extends SingleValueStatistics>) 
				this.getJspContext().findAttribute(statistics);
		if (statList == null || statList.size() == 0) {
			out.println ("No statistics found!");
			return;
		}
		
		PageContext pc = (PageContext) getJspContext();
		HttpServletRequest request = (HttpServletRequest) pc.getRequest();
		
		MultiLayerStatistics multilayerStat = MultiLayerStatistics.constructor(request, statList);
		
		
		
		out.println ("<UL>");
		
		out.println (multilayerStat.toHTML(statistics, request));
		
		out.println ("</UL>");

	}
	

	public String getStatistics() {
		return statistics;
	}

	public void setStatistics(String statistics) {
		this.statistics = statistics;
	}

	
	private static class MultiLayerStatistics {
		public static final long SECOND_X = 3600;	//1 hour
		public static final long THIRD_Y = 900;	//15 minutes
		
		static MultiLayerStatistics constructor(HttpServletRequest request, List<? extends SingleValueStatistics> statList) {
			AwrSetting awr = (AwrSetting) request.getSession().getAttribute("awrsetting");
			int xBlock = 60 / awr.getInterval();
			int yBlock = 1;
			if (request.getParameter("x_block") != null && request.getParameter("y_block") != null) {
				xBlock = Integer.parseInt(request.getParameter("x_block"));
				yBlock = Integer.parseInt(request.getParameter("y_block"));				
			}
			else {
				request.setAttribute("x_block", xBlock);
				request.setAttribute("y_block", yBlock);
			}
			
			xBlock *= awr.getInterval() ;
			yBlock *= awr.getInterval() ;
			
			System.out.println ("======== x: " + xBlock + " (" + xBlock/60 + "), y: " + yBlock + " (" + yBlock/60 + ")")
;			MultiLayerStatistics thirdStat = null, secondStat = null, firstStat = null;
			 
			for (int i=0; i<statList.size(); i++) {
				MultiLayerStatistics stat = new MultiLayerStatistics(statList.get(i));
				
				if (thirdStat == null) {
					thirdStat = new MultiLayerStatistics(statList.get(i));
					secondStat = new MultiLayerStatistics(statList.get(i));
					firstStat = new MultiLayerStatistics(statList.get(i));	
					
					thirdStat.addSubStat(stat);
					secondStat.addSubStat(thirdStat);
					firstStat.addSubStat(secondStat);
					continue;
				}
				
				
				if (secondStat.getTS().getTime()/60000 - stat.getTS().getTime()/60000 >= xBlock) {
					secondStat = new MultiLayerStatistics(statList.get(i));
					firstStat.addSubStat(secondStat);
				}
								
				if (thirdStat.getTS().getTime()/60000 - stat.getTS().getTime()/60000 >= yBlock) {
					thirdStat = new MultiLayerStatistics(statList.get(i));
					secondStat.addSubStat(thirdStat);
				}
				thirdStat.addSubStat(stat);
				
			}
			
			return firstStat;
			
		}
		
		private SingleValueStatistics st;
		private ArrayList<MultiLayerStatistics> subStats =  new ArrayList<AggregatedValue.MultiLayerStatistics>();
		MultiLayerStatistics (SingleValueStatistics stat) {
			this.st = stat;
		}
		
		public void addSubStat(MultiLayerStatistics stat) {
			subStats.add(stat);
		}
		
		public SingleValueStatistics getAggregatedStat() {
			if (subStats.size() == 0) return st;
			
			ArrayList<SingleValueStatistics> allAggregatedStats = new ArrayList<SingleValueStatistics>();
			for (int i=0; i<subStats.size(); i++) {
				allAggregatedStats.add(subStats.get(i).getAggregatedStat());
			}
			return allAggregatedStats.get(0).aggregate(allAggregatedStats);
			
		}
		
		public Timestamp getTS() {
			return st.getTs();			
		}
		
		public String toHTML(String statistics, HttpServletRequest request) {
			if (subStats.size() > 1) {
				SingleValueStatistics agreStat = getAggregatedStat();
				String html = "<li>" 
						+ agreStat.toHtml() + " " + ThresholdUtil.getHtmlHealthStatus(statistics, request, agreStat) 
						+ "<ul>";
				for (int i=0; i<subStats.size(); i++) {
					html += subStats.get(i).toHTML(statistics, request);
				}
				html 	+=  "</ul>"
						+ "</li>";
				return html;
			}
			else return "<li>" + st.toHtml() + " " + ThresholdUtil.getHtmlHealthStatus(statistics, request, st) + "</li>";
		}
	}
}
